#ifndef VBOMANAGER_H
#define VBOMANAGER_H

#include "includes.h"
#include "QuickArray.h"
#include "vboVoxel.h"
#include "voxel.h"

class VBOManager
{
    QGLBuffer vbuf, ibuf;
    int icount;
    int chunk_to_index(int x, int y, int z) const;
    int vector_to_index(int x, int y, int z) const;
public:
    VBOManager(short x, short y, short z);
    ~VBOManager();
    void addVoxel(voxel& v,int x, int y, int z);
    void render();
    void reset();
    void writeVBOVoxel(int index,vboVoxel& v);
    vboVoxel readVBOVoxel(int index);
    void writeVBOIndex(unsigned short i);
    unsigned short readVBOIndex(int index);
    void setVoxelColor(int x, int y, int z, colour& c);
};

inline
int VBOManager::chunk_to_index(int x, int y, int z) const{//optimize later
    return MUL_CHNKSIZE(MUL_CHNKSIZE(x)) + MUL_CHNKSIZE(y) + z;
}

inline
int VBOManager::vector_to_index(int x, int y, int z) const{//optimize later
    return MUL_CHNKSIZE(MUL_CHNKSIZE(MOD_CHNKSIZE(x))) + MUL_CHNKSIZE(MOD_CHNKSIZE(y)) + MOD_CHNKSIZE(z);
}

inline
void VBOManager::reset(){
    icount=0;
}

inline
void VBOManager::writeVBOVoxel(int index,vboVoxel& v){
    vbuf.bind();
    vbuf.write(index*sizeof(vboVoxel),&v,sizeof(vboVoxel));
    vbuf.release();
}

inline
vboVoxel VBOManager::readVBOVoxel(int index){
    vboVoxel temp;
    vbuf.bind();
    vbuf.read(index*sizeof(vboVoxel),&temp,sizeof(vboVoxel));
    vbuf.release();
    return temp;
}

inline
void VBOManager::writeVBOIndex(unsigned short i){
    ibuf.bind();
    ibuf.write(icount*sizeof(unsigned short),&i,sizeof(unsigned short));
    ibuf.release();
    ++icount;
}

inline
unsigned short VBOManager::readVBOIndex(int index){
    unsigned short temp;
    ibuf.bind();
    ibuf.read(index*sizeof(unsigned short),&temp,sizeof(unsigned short));
    ibuf.release();
    return temp;
}

inline
void VBOManager::setVoxelColor(int x, int y, int z, colour& c){
    unsigned short index=vector_to_index(x,y,z);
    vboVoxel temp=readVBOVoxel(index);
    temp.setColor(c);
    writeVBOVoxel(index,temp);
}

#endif // VBOMANAGER_H
